//
//  QRegExp.m
//  dump_12306
//
//  Created by qiaolun on 6/1/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "QRegExp.h"


@implementation QRegExp

+ (NSArray *) matchAll:(NSString *)pattern withString:(NSString *)subject flags:(int)flag {

	// compile
	int error_compile;
#define ERROR_STRING_LEN 1024
	char error_string[ERROR_STRING_LEN];

	regex_t preg;
	error_compile = regcomp(&preg, [pattern UTF8String], flag);
	if(error_compile != 0){
		regerror(error_compile, &preg, error_string, ERROR_STRING_LEN);
		NSLog(@"compile error: %@, %s", pattern, error_string);
		regfree(&preg);
		return nil;
	}
	
	NSMutableArray *matches = [NSMutableArray arrayWithCapacity:20];
	
	// exec
#define MAX_MATCH 20
	size_t nmatch = MAX_MATCH;
	regmatch_t pmatch[MAX_MATCH];
	int offset = 0;
	const char* t_subject = [subject UTF8String];

	while(0 == regexec(&preg, t_subject+offset, nmatch, pmatch, 0)){
		const char* t_buf = t_subject + offset;
		int matched = 0;
		NSMutableArray *matchOne = [NSMutableArray arrayWithCapacity:nmatch];
		int i;
		for(i = 0; i < nmatch; i++){
			if(pmatch[i].rm_so != -1){
				matched = 1;
				size_t len = pmatch[i].rm_eo - pmatch[i].rm_so;
				char match_str[len+1];
				memcpy(match_str, t_buf + pmatch[i].rm_so, len);
				match_str[len] = 0;
				[matchOne addObject:[NSString stringWithUTF8String:match_str]];
			}
		}
		
		[matches addObject:matchOne];
		
		if(matched == 0){
			// not matched, no need continue
			break;
		} else {
			// start search from this end offset
			offset += pmatch[0].rm_eo;
		}
	}
	
	regfree(&preg);
	if([matches count] > 0){
		return [NSArray arrayWithArray:matches];
	} else {
		return nil;
	}
}

@end
